import { createVNode, render, VNode } from "vue";
import Popup from "@/components/popup/popup"
import {nanoid} from "nanoid";

export type Config = {
  // @ts-ignore
  // 渲染的目标元素
  target?: HTMLElement
  // 标题
  title?: string
  // 弹出层宽度
  width?: number | "auto"
  // 弹出层高度
  height?: number | "auto"
  // 是否启用mask遮罩
  mask?: boolean
  // 是否启用拖拽
  drag?: boolean
  // 配置根标签样式: 格式为StyleObject字符串
  rootElStyle?: string
  noHeader?: boolean
}

/**
 * 函数式弹出层
 * 默认挂载到body元素下；
 * 内部设有两个插槽 header, default；
 * 传递的VNode其内部使用的所有组件必须为手动引入，否则会导致无法解析；
 * 请不要直接将此方法绑定在组件on上，会造成第一个参数为Event对象；
 * @param slots 插槽配置 - 值必须是一个VNode
 * @param config 弹出层配置
 */

export function createPopup(
  slots: { header?: (close: () => void) => VNode; default: (close) => VNode }, config?: Config) {
  // @ts-ignore
  const _body: HTMLElement = document.body
  const _container: HTMLDivElement = document.createElement("div")
  const key = nanoid()
  const _defaultConfiguration: Config = {
    target: _container,
    title: "",
    width: "auto",
    height: "auto",
    mask: true,
    drag: false,
    rootElStyle: "",
    noHeader: false
  }

  if(!config?.target) {
    _body.appendChild(_container)
    _container.id = "popup_container_" + key
  }

  const popup = createVNode(Popup, {
    config: Object.assign(_defaultConfiguration, config),
    id: !config?.target? key : undefined,
    onClose: _closeWindow
  }, slots)

  // default: ()=> slots? h(slots) : h("h1", "未传递任何VNode")
  // @ts-ignore
  render(popup, _defaultConfiguration.target)

  /**
   * 内部方法-弹窗关闭
   */
  function _closeWindow() {
    // @ts-ignore
    render(null, _defaultConfiguration.target)
    !config?.target && _body.removeChild(_container)
  }

  return popup
}
